/*
package org.scolring.eclipse.scol.editor.rules;
*/

package testplugineditor.editors;

import org.eclipse.jface.util.Assert;
import org.eclipse.jface.text.rules.ICharacterScanner;
import org.eclipse.jface.text.rules.IRule;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.Token;

/**
 * RÃ¨gle dÃ©tectant les nombres hexadÃ©cimaux (de la forme 0x1234567890ABCDEF).  
 * @author SÃ©bastien Le Ray
 */
public class HexNumberRule implements IRule
{

		private IToken fToken;
		private static final String hexChars = "0123456789ABCDEFabcdef";
		
		
		/**
		 * Constructeur.
		 * La rÃ¨gle renverra token si lors de l'analyse
		 * elle trouve une chaine hexadÃ©cimale. 
		 * @param token Token Ã  renvoyer en cas de succÃ¨s.
		 */
		public HexNumberRule(IToken token) {
			Assert.isNotNull(token);
			fToken = token;
		}
		
		/**
		 * Indique si le caractÃ¨re passÃ© en paramÃ¨tre est un caractÃ¨re
		 * hexadÃ©cimal valide.
		 * @param c CaractÃ¨re Ã  analyser.
		 * @return <code>true</code> si le caractÃ¨re est un caractÃ¨re
		 * hexadÃ©cimal, <code>false</code> sinon.
		 */
		private boolean isHexDigit(int c) {
			return (hexChars.indexOf(c) >= 0);
		}
		
		/**
		 * DÃ©termine si l'on est en prÃ©sence d'une chaine
		 * correspondant Ã  un nombre hexadÃ©cimal ou non.
		 * AppelÃ© par l'SCOLCodeScanner (via le RuleBasedScanner).
		 * @param scanner Scanner permettant de lire le texte.
		 * @return Le token passÃ© au constructeur si la chaine est une chaine hexa.
		 * <code>Token.UNDEFINED</code> sinon ce qui permet de continuer l'analyse.
		 * @see org.eclipse.jface.text.rules.IRule#evaluate(org.eclipse.jface.text.rules.ICharacterScanner)
		 */
		public IToken evaluate(ICharacterScanner scanner) 
		{
			int c = scanner.read();
			
			if(isHexDigit(c)) 
			{		// 0x2aedfh
			    if(c == '0') 
			    {	// 0xe424
					c = scanner.read();
					if((char) c == 'x') {
						do {
							c = scanner.read();
						} while(isHexDigit(c));
						scanner.unread();
						return fToken;
					}
					scanner.unread();	// unread le premier caractÃ¨re.
			    }
				int size = 0;
				do {
					c = scanner.read();
					++size;
				} while(isHexDigit((char) c));
				if(c == 'h' || c == 'H') {
					return fToken;
				}
				for( ; size > 0 ; --size) {		// unread tout
					scanner.unread();
				}
			}
			scanner.unread();		// Unread le premier caractÃ¨re
			return Token.UNDEFINED;
		}

}